/**
 * User: alesj
 * Date: 10.1.2006
 * Time: 18:48:19
 * 
 * (C) Genera Lynx d.o.o.
 */

package com.alesj.blueberry.sar.smpp.impl;

import com.alesj.blueberry.sar.smpp.SMPPService;
import ie.omk.smpp.Connection;
import ie.omk.smpp.message.EnquireLink;
import ie.omk.smpp.message.EnquireLinkResp;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.IOException;
import java.util.Set;
import java.util.TreeSet;

/**
 * Pinging smsc to establish connection status.
 *
 * @author <a href="mailto:ales.justin@genera-lynx.com">Ales Justin</a>
 *
 * @jmx.mbean
 * @jboss.xmbean
 */
public class SMPPPingDeamon implements Runnable, SMPPPingDeamonMBean {

    private final Log log = LogFactory.getLog(getClass());

    private long intervalTime = 60000; //1min
    private long allowedPingDifference = 10;
    private SMPPService smppService;
    private boolean running = true;
    private Set<Integer> counter = new TreeSet<Integer>();

    public void runDeamon() {
        new Thread(this).start();
    }

    /**
     * Running in a new thread.
     */
    public void run() {
        while(running) {
            try {
                Connection connection = smppService.getConnection();
                if (connection != null && connection.isBound()) {
                    EnquireLink el = new EnquireLink();
                    log.debug("Requesting enquiry link ...");
                    //pinging
                    connection.sendRequest(el);
                    counter.add(el.getSequenceNum());
                }
                Thread.sleep(getIntervalTime());
            } catch (InterruptedException e) {
                //ignored
            } catch (IOException e) {
                log.error("IO exception while pinging: " + e.getMessage());
                smppService.notifyOfFailure(e);
            } catch(Exception e) {
                log.error("Exception while sending ping request: " + e.getMessage());
                smppService.notifyOfFailure(e);
            }
        }
        log.info("Exiting ping deamon ...");
    }

    /**
     * Apply received response.
     *
     * @param enquireLinkResp
     */
    public void responseReceived(EnquireLinkResp enquireLinkResp) {
        Integer responseSeq = enquireLinkResp.getSequenceNum();
        counter.remove(responseSeq);
    }

    // mbean support

    /**
     * @jmx.managed-attribute
     */
    public void setSMPPService(SMPPService smppService) {
        this.smppService = smppService;
        this.smppService.setPingDeamon(this);
    }

    /**
     * @jmx.managed-operation
     */
    public void startDeamon() {
        running = true;
    }

    /**
     * @jmx.managed-operation
     */
    public void stopDeamon() {
        running = false;
    }

    /**
     * @jmx.managed-attribute
     */
    public long getIntervalTime() {
        return intervalTime;
    }

    /**
     * @jmx.managed-attribute
     */
    public void setIntervalTime(long intervalTime) {
        this.intervalTime = intervalTime;
    }

    /**
     * @jmx.managed-attribute
     */
    public long getAllowedPingDifference() {
        return allowedPingDifference;
    }

    /**
     * @jmx.managed-attribute
     */
    public void setAllowedPingDifference(long allowedPingDifference) {
        this.allowedPingDifference = allowedPingDifference;
    }

}
